from __future__ import division

import os
import random

import pygame

from settings import settings

class Tile(object):
	_match_edges = True
	_frame_delay = 0
	
	def __init__(self, position):		
		self.position = position
		
		self._frame = 0
		self._frame_tick = 0
		self._configuration = None
		
		self.variants = (
			(random.randint(0, 3), random.randint(0, 3)),
			(random.randint(0, 3), random.randint(0, 3)))
	
	def _subtiles(self, configuration):
		"""This is a painful 'algorithm' for finding the right subtiles to use
		to match similar tile edges.
		"""
		tl = 0
		tr = 1
		bl = 2
		br = 3
		
		if self._match_edges:
			if configuration[0 + 1][-1 + 1]:			
				if configuration[-1 + 1][0 + 1]:			
					if configuration[-1 + 1][-1 + 1]:
						tl += 12
					else:
						tl += 8
				else:
					tl += 6
			elif configuration[-1 + 1][0 + 1]:
				tl += 4
						
			if configuration[-1 + 1][0 + 1]:
				if configuration[0 + 1][1 + 1]:
					if configuration[-1 + 1][1 + 1]:
						tr += 12
					else:
						tr += 8
				else:
					tr += 4
			elif configuration[0 + 1][1 + 1]:
				tr += 5
						
			if configuration[0 + 1][1 + 1]:	
				if configuration[1 + 1][0 + 1]:
					if configuration[1 + 1][1 + 1]:
						br += 12
					else:
						br += 8
				else:
					br += 4
			elif configuration[1 + 1][0 + 1]:
				br += 2
						
			if configuration[1 + 1][0 + 1]:
				if configuration[0 + 1][-1 + 1]:
					if configuration[1 + 1][-1 + 1]:
						bl += 12
					else:
						bl += 8
				else:
					bl += 2
			elif configuration[0 + 1][-1 + 1]:
				bl += 5
		
		result = [[tl, tr], [bl, br]]
		
		for y, row in enumerate(result):
			for x, subtile in enumerate(row):
				if subtile >= 12:
					result[y][x] = 12 + self.variants[y][x]
			
			result[y] = tuple(result[y])
		result = tuple(result)
		
		return result
	
	def configure(self, configuration):
		if self._match_edges:
			self._configuration = self._subtiles(configuration)
		else:
			configuration = ((0, 1), (2, 3))
	
	def update(self, frame):
		return False		
	
	def draw(self, surface, position=None):
		if not position:
			position = self.position
		
		if self._match_edges:
			size = 16
		else:
			size = 32
		
		frame = self._frame * size
		
		draw_x, draw_y = position
		
		for y, row in enumerate(self._configuration):
			for x, subtile in enumerate(row):
				rect = (subtile * size, frame, 16, 16)
				
				surface.blit(self.graphic, (draw_x + (x * 16), draw_y + (y * 16)), rect)

class AnimatedTile(Tile):
	def update(self, frame):
		self._frame_tick += 1
	
		if self._frame_tick > self._frame_delay:
			self._frame_tick = 0
			self._frame += 1
		
			if self._frame >= self._frames:
				self._frame = 0
			
			return True	
		else:
			return False

def tile(tile_graphic, frame_delay=1):
	tile_graphic = pygame.image.load(os.path.join(settings.paths.graphics, "tiles/%s.png" % tile_graphic)).convert_alpha()
	
	frames = tile_graphic.get_height() // 16
	
	if frames > 1:
		Class = AnimatedTile
	else:
		Class = Tile
		
	class CustomTile(Class):
		graphic = tile_graphic
		_frames = frames
		_frame_delay = frame_delay
		
	return CustomTile
